2oneweek.dev

24. 클로저 (Closure)란?

    Tags

  • JavaScript
24. 클로저 (Closure)란? thumbnail

Closure

  • function Object를 생성할 때, 함수가 속한 스코프를 function Object의 내부 프로퍼티 [[Scope]]에 설정하고,
  • 함수가 호출되었을 때, [[Scope]]의 프로퍼티를 사용하는 매커니즘을 클로저라 한다.

클로저는 지금까지 Scope를 사용한 것의 논리적인 설명에 불과하다.


클로저 논리

실행컨텍스트 : { 렉시컬환경컴포넌트 : { 환경레코드 : { 선언적환경레코드 : {}, 오브젝트환경레코드 : {} } 외부렉시컬환경참조: {}, }, 변수환경컴포넌트 : {}, this바인딩컴포넌트 : {} }
  • 엔진은 function Object가 호출되면 실행 컨텍스트를 만들게 되는데, 함수 내부에 위치한 변수와 함수를 선언적 환경 레코드에 설정하게 된다.
  • 또한 엔진은 function Object의 [[Scope]]에 저장된 변수와 함수를 외부 렉시컬 환경 참조에 바인딩 한다.
    • 그래서 우리는, 함수가 속한 Scope에 있는 변수와 함수를 참조해서 사용할 수 있게 된다. 참조이기 때문에, 내부에서 변경한 것이 외부에서도 적용된다.

외부 렉시컬 환경 참조에 있는 것을, 함수 내부에 있는 것처럼 사용하는 것이 클로저의 논리다.

구조에 대해 이해하고 있으면, 클로저라는 로직은 이해가 쉽다.


클로저 논리를 사용하여 설명

function book() { var point = 100; var getPoint = function (param) { point = point + param; return point; }; return getPoint; //함수를 반환 } var obj = book(); console.log(obj(200));
  • 외부 렉시컬 환경 참조 덕분에, 함수 안에 함수가 바깥의 함수에 선언된 변수를 사용할 수 있게 된다.

    • 이와 비슷한 것으로 객체 안의 함수를 호출할 때, 함수가 객체에 존재하는 변수를 참조하기 위해 this를 사용하는 것과 비슷하다.
    • 그러나 이렇게 외부 렉시컬 환경 참조 덕분에 this와 같은 키워드를 사용하지 않고도 접근이 가능하다.
  • getPoint 반환해주고 다른 곳에서 쓰더라도, 엔진이 getPoint function Object를 생성해줄 때, [[Scope]]가 결정되기 때문에(즉, Closure가 생성된다.), 함수를 호출하는 시점이 언제든 간에, book 내부의 변수에 접근할 수 있다.\

    • 실행 컨텍스트가 만들어지면서 외부 렉시컬 환경 참조에 [[Scope]]가 들어가기 때문이다.

이렇게 외부 렉시컬 환경 참조에, function Object의 [[Scope]]가 바인딩된 환경을 클로저라고 한다.

  • 선언적 환경 레코드에 변수가 없으면, 외부 렉시컬 환경 참조에서 식별자 해결을 할 수 있다. 여기까지가 클로저라고 보면 된다.



클로저와 무명함수

  • 익명함수 안에 작성한 값과 함수는, 익명 함수가 끝나면 지워진다. 익명 함수는 저장하지 않으려는 의도로 사용된다.

  • 클로저는 함수 밖 스코프의 변수와 함수를 사용할 수 있다. 변수는 외부에서 직접 접근할 수 없도록 보호해야 한다.

  • 익명함수 안에서, 클로저의 변수를 가진 함수를 반환하면, 함수의 재사용과 정보 보호를 할 수 있다.

var book = (function () { var point = 100; return function getPoint(param) { return point + param; }; })(); console.log(book(200));
  1. 엔진은 function getPoint를 만나 getPoint function Object를 생성하고 [[Scope]]를 설정한다.
  2. 그리고 실행과정에서 getPoint Function Object를 반환한다.
    • 즉시 실행 함수(익명함수와 바로 호출된 것)는 반환되자마자, 안에 있는 내용은 날라가게 된다.
    • 따라서 point 변수는 바뀔 여지가 없다. 즉 보호가 가능하다.
  3. book 식별자는 getPoint Function Object이기 때문에, point 변수에 접근이 가능하다.

이렇게 즉시 실행 함수를 쓰면, 내부 변수를 가릴 수 있다. 더불어 클로저를 이용하여 즉시실행함수가 함수를 반환하게 되면, 내부 프로퍼티를 가리면서 반환된 함수를 재사용할 수 있다.

Written by@2-one-week
현재 블로그 개발 중

GitHubLinkedIn